﻿using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Services;
using System;
using System.Configuration;
using System.Diagnostics;
using System.Linq.Expressions;

namespace ZhongchenZhou.EnterpriseLibrary.Logging.DynamicsCrm2011.Configuration
{
    [ResourceDescription(typeof(DesignResources), "DynamicsCrm2011TraceListenerDataDescription")]
    [ResourceDisplayName(typeof(DesignResources), "DynamicsCrm2011TraceListenerDataDisplayName")]
    public class DynamicsCrm2011TraceListenerData : TraceListenerData
    {
        private const string crmConnectionStringNameProperty = "crmConnectionStringName";
        private const string formatterNameProperty = "formatter";

        public DynamicsCrm2011TraceListenerData()
            : base(typeof(DynamicsCrm2011TraceListener))
        {
            this.ListenerDataType = typeof(DynamicsCrm2011TraceListener);
        }

        public DynamicsCrm2011TraceListenerData(string name, string crmConnectionStringName, string formatterName)
            : this(name, crmConnectionStringName, formatterName, TraceOptions.None, SourceLevels.All)
        {
        }

        public DynamicsCrm2011TraceListenerData(string name,
                                                  string crmConnectionStringName,
                                                  string formatterName,
                                                  TraceOptions traceOutputOptions,
                                                  SourceLevels filter)
            : base(name, typeof(DynamicsCrm2011TraceListener), traceOutputOptions, filter)
        {
            CrmConnectionStringName = crmConnectionStringName;
            Formatter = formatterName;
        }

        /// <summary>
        /// Gets and sets the crm connection string name.
        /// </summary>
        [ConfigurationProperty(crmConnectionStringNameProperty, IsRequired = true)]
        [ResourceDescription(typeof(DesignResources), "DynamicsCrm2011TraceListenerDataCrmConnectionStringNameDescription")]
        [ResourceDisplayName(typeof(DesignResources), "DynamicsCrm2011TraceListenerDataCrmConnectionStringNameDisplayName")]
        public string CrmConnectionStringName
        {
            get { return (string)base[crmConnectionStringNameProperty]; }
            set { base[crmConnectionStringNameProperty] = value; }
        }

        [ConfigurationProperty(formatterNameProperty, IsRequired = false)]
        [Reference(typeof(NameTypeConfigurationElementCollection<FormatterData, CustomFormatterData>), typeof(FormatterData))]
        [ResourceDescription(typeof(DesignResources), "DynamicsCrm2011TraceListenerDataFormatterDescription")]
        [ResourceDisplayName(typeof(DesignResources), "DynamicsCrm2011TraceListenerDataFormatterDisplayName")]
        public string Formatter
        {
            get { return (string)base[formatterNameProperty]; }
            set { base[formatterNameProperty] = value; }
        }

        /// <summary>
        /// Returns a lambda expression that represents the creation of the trace listener described by this
        /// configuration object.
        /// </summary>
        /// <returns>A lambda expression to create a trace listener.</returns>
        protected override Expression<Func<TraceListener>> GetCreationExpression()
        {
            return () => new DynamicsCrm2011TraceListener(new OrganizationService(new CrmConnection(CrmConnectionStringName)), Container.ResolvedIfNotNull<ILogFormatter>(Formatter));
        }
    }
}
